

local handle_manager = {}
base.handle_manager = handle_manager
handle_manager.handle_map = {}
handle_manager.mt_map = {}


--handle_manager对象，是类型和类的映射表
local handle_manager_mt = {}

function handle_manager_mt:OnInit()
    if self.on_init then
        self:on_init()
    end
end

function handle_manager_mt:OnRemove()
    if self.on_remove then
        self:on_remove()
    end
end

function handle_manager_mt:init()
    handle_manager.handle_map[self.handle_type][self.handle] = self
    self:OnInit()
    base.game:event_notify(self.key_event_create, self)
    if self.on_init_over then
        self:on_init_over()
    end
end

function handle_manager_mt:remove()
    if self.removed then
        return
    end
    --log.info('handle_manager_mt:remove', self.handle_type, self.handle)
    self.removed = true
    handle_manager.handle_map[self.handle_type][self.handle] = nil
    self:OnRemove()
    --log.info(':remove key_event_update', self.key_event_update)
    --log.info(':remove key_event_remove', self.key_event_remove)
    base.game:event_notify(self.key_event_update, self)
    base.game:event_notify(self.key_event_remove, self)
end

function handle_manager_mt:OnSet(key,value)
    if self.on_set then
        self:on_set(key, value)
    end
end

function handle_manager_mt:OnSetAct(key,func)
    if not self._OnSetAct[key] then
        self._OnSetAct[key] = {}
    end
    table.insert(self._OnSetAct[key], func)
end

function handle_manager_mt:set(default_key,value)
    --log.info('[handle_manager] set', default_key, value, utils.get_show_table_str(self))
    local is_table = type(default_key) == 'table'
    local key = default_key
    if is_table then
        --log.info('[handle_manager] set_table', default_key, value, utils.get_show_table_str(self))
        key = table.concat(key,'-')
    end
    if self.on_set_start then
        self:on_set_start(key, value)
    end
    if is_table then
        local tb = self
        local max = #default_key
        for i = 1, max-1 do
            if i < max then
                --传进来key_list，在为空时自动创建table
                if not tb[default_key[i]] then
                    tb[default_key[i]] = {}
                end
                tb = tb[default_key[i]]
            end
        end
        tb[default_key[#default_key]] = value
        --log.info('[handle_manager] set_table B', key, value, utils.get_show_table_str(self))
    else
        self[key] = value
    end
    if self._OnSetAct[key] then
        for k,v in ipairs(self._OnSetAct[key]) do
            v(self, key, value)
        end
    end
    if is_table then
        if self._OnSetAct[default_key[1]] then
            for k,v in ipairs(self._OnSetAct[default_key[1]]) do
                v(self, default_key[1], value)
            end
        end
    end
    self:OnSet(key, value)
    base.game:event_notify(self.key_event_set, self, key, value, default_key)
    base.game:event_notify(self.key_event_update, self)
end

function handle_manager_mt:sync_act_set(act, func)
    self.sync_act[act] = func
end

function handle_manager:register(key)
    if handle_manager.mt_map[key] then
        return handle_manager.mt_map[key]
    end
    if not handle_manager.handle_map[key] then
        handle_manager.handle_map[key] = {}
    end
    local sync_act = {}
    local mt = {
        sync_id = 'ho_' .. key,
        handle_type = key,
        key_event_set = key .. '_on_set',
        key_event_update = key .. '_on_update',
        key_event_create = key .. '_on_create',
        key_event_remove = key .. '_on_remove',
        sync_act = sync_act,
        sync_key = {
            create = 1,
            remove = 2,
            set = 3,
        },
        _OnSetAct = {},
        handle_map = handle_manager.handle_map[key],
    }
    setmetatable(mt, {__index = handle_manager_mt})
    handle_manager.mt_map[key] = mt

    --create
    mt:sync_act_set( mt.sync_key.create, function(target, msg)
        --log.info('create act', target, target and utils.get_show_table_str(target))
        --log.info('create msg', msg, utils.get_show_table_str(msg))
        if target then
            log.warn('handle_manager', key, 'init', 'target already exists', target, utils.get_show_table_str(msg), debug.traceback())
            return
        end
        local handle = msg[2]
        local args = msg[3]
        local data = {
            handle = handle,
        }
        if args then
            for k,v in pairs(args) do
                data[k] = v
            end
    	else
            log.warn('[警告] handle_manager create', key, '没有参数', utils.get_show_table_str(msg))
        end
        setmetatable( data, {__index = mt})
        data:init()

        return data
    end)

    --remove
    mt:sync_act_set( mt.sync_key.remove, function(target, msg)
        if not target then
            return
        end
        target:remove()
    end)
    
    --set
    mt:sync_act_set( mt.sync_key.set, function(target, msg)
        if not target then
            return
        end
        local count = msg[3]
        --log.info('[handle_manager] sync_set', mt.sync_id, utils.get_show_table_str(msg))
        for i = 1, count do
            target:set(msg[3+i*2-1],msg[3+i*2])
        end
    end)

    local target_handle_map = handle_manager.handle_map[key]
    base.proto[mt.sync_id] = function(data)
        if not data then
            log.warn('proto handle_manager 错误的data', mt.sync_id, utils.get_show_table_str(data))
            return
        end
        --log.info('proto handle_manager', mt.sync_id, (type(data)==table) and utils.get_show_table_str(data) or data)
        local act_id = data[1]
        local handle = data[2]
        local target = target_handle_map[handle]
        --log.info('proto handle_manager', mt.sync_id, act_id, handle, target, utils.get_show_table_str(data))
        if sync_act[act_id] then
            sync_act[act_id]( target, data)
        else
            log.warn('handle_manager 错误的act_id', mt.sync_id, act_id, 'no sync_act', utils.get_show_table_str(data))
        end
    end
    return mt        
end

function handle_manager:get( handle_type, handle)
    if not handle or handle == 0 then
        --log.warn('handle_manager:get 错误的handle', handle)
        return
    end
    if not handle_manager.handle_map[handle_type] then
        --log.warn('handle_manager:get 错误的handle_type', handle_type, handle)
        return
    end
    return handle_manager.handle_map[handle_type][handle]
end

function handle_manager:get_all_map( handle_type)
    if not handle_manager.handle_map[handle_type] then
        --log.warn('handle_manager:get 错误的handle_type', handle_type, handle)
        return
    end
    return handle_manager.handle_map[handle_type]
end

--需要由客户端来创建handle_manager
--base.proto.handle_manager_key = function(list)
--    handle_manager.handle_map = {}
--    for _, key in ipairs(list) do
--        handle_manager:register(key)
--    end
--end

